package de.fhkl.gatav.ut.camera5classthread;

import de.fhkl.gatav.ut.camera5classthread.CamSurfaceHolder;
import de.fhkl.gatav.ut.camera5classthread.R;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class CameraClassThreadActivity extends Activity implements OnTouchListener {

	public CamSurfaceHolder	camSurface;
	
    Matrix oldMatrix = new Matrix();
    Matrix currentMatrix = new Matrix();
    
	TouchType touchState = TouchType.NONE;
    final static float MIN_DIST = 50;
    static float eventDistance = 0;
    static PointF center = new PointF( 0.0f, 0.0f );
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main); 
        
        ImageView view = (ImageView) findViewById(R.id.imageView);
        camSurface = (CamSurfaceHolder) findViewById(R.id.camSurface);
        
        if (view.getImageMatrix() != null)
            oldMatrix.set(view.getImageMatrix());
        view.setOnTouchListener(this);
    }
    
    @Override
	protected void onPause() {
		if (camSurface!=null) {
			camSurface.releaseCam();
		}
		super.onPause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (camSurface!=null) {
			camSurface.reOpenCam();
		}
	}
	
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    	ImageView view = (ImageView) v;
    	int action = event.getAction();
    	
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            //Primary touch event starts: remember touch down location
            touchState = TouchType.DRAG;
//            firstFingerPos = new PointF( event.getX(0), event.getY(0));
            center.set(event.getX(0), event.getY(0));
            if (view.getImageMatrix() != null)
                oldMatrix.set(view.getImageMatrix());
            break;
            
        case MotionEvent.ACTION_POINTER_DOWN:
            //Secondary touch event starts: remember distance and center
            eventDistance = calcDistance(event);
            center = calcMidpoint(event);
            if (eventDistance > MIN_DIST) {
                touchState = TouchType.ZOOM;
                if (view.getImageMatrix() != null)
                    oldMatrix.set(view.getImageMatrix());    
            }
            break;
            
        case MotionEvent.ACTION_MOVE:
            if (touchState == TouchType.DRAG) {
                //Single finger drag, translate accordingly
                currentMatrix.set(oldMatrix);
                currentMatrix.postTranslate(event.getX(0) - center.x,
                        event.getY(0) - center.y);
                
            } else if (touchState == TouchType.ZOOM) {
                //Double-finger zoom, scale accordingly around center
                float dist = calcDistance(event);
                if (dist > MIN_DIST) {
                    currentMatrix.set(oldMatrix);
                    float scale = dist / eventDistance;
                    currentMatrix.postScale(scale, scale, center.x, center.y);
                }
            }
            view.setImageMatrix(currentMatrix);
            break;
            
        case MotionEvent.ACTION_UP:
        	//Last finger up
            touchState = TouchType.NONE;
            // save matrix
            oldMatrix.set(view.getImageMatrix());
            break;
            
        case MotionEvent.ACTION_POINTER_UP:
        	//One of two fingers up
            touchState = TouchType.DRAG;
            // save matrix
            oldMatrix.set(view.getImageMatrix());
            //Update touch down location for drag event to holding finger
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            switch (pointerIndex) {
            case 0:
                center = new PointF( event.getX(1), event.getY(1) );
                break;
            case 1:
                center = new PointF( event.getX(0), event.getY(0) );
                break;
            }
            break;
        }
        return true;
    }

    private float calcDistance(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    private PointF calcMidpoint(MotionEvent event) {
        return new PointF( (event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
    }

}